﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework;

namespace Aphysoft.Vate
{
    public partial class Vate
    {
        #region Properties
        /// <summary>
        /// Gets a value indicating whether the input is ready to accept.
        /// </summary>
        public static bool InputReady
        {
            get
            {
#if DEBUG
                if (Debug.IsDebugConsoleActive)
                    return false;
                else
                    return true;
#else
                return true;
#endif
            }
        }
        /// <summary>
        /// Old state of keystroke.
        /// </summary>
        private static KeyboardState oldKeyboardState;
        /// <summary>
        /// Gets old recorded keystroke state.
        /// </summary>
        public static KeyboardState OldKeyboardState
        {
            get { return oldKeyboardState; }
            set { oldKeyboardState = value; }
        }
        /// <summary>
        /// State of keystroke recorded by a keyboard input device.
        /// </summary>
        private static KeyboardState keyboardState;
        /// <summary>
        /// Gets a state of keystroke recorded by a keyboard input device.
        /// </summary>
        public static KeyboardState KeyboardState
        {
            get { return keyboardState; }
            set { keyboardState = value; }
        }
        /// <summary>
        /// Old state of mouse.
        /// </summary>
        private static MouseState oldMouseState;
        /// <summary>
        /// Gets old recorded mouse state.
        /// </summary>
        public static MouseState OldMouseState
        {
            get { return oldMouseState; }
            set { oldMouseState = value; }
        }
        /// <summary>
        /// State of mouse.
        /// </summary>
        private static MouseState mouseState;
        /// <summary>
        /// Gets a state of mouse recorded by a mouse input device.
        /// </summary>
        public static MouseState MouseState
        {
            get { return mouseState; }
            set { mouseState = value; }
        }
        /// <summary>
        /// Elapsed time when keyboard key is being pressed.
        /// </summary>
        private static float keyPressedElapsedTime = 0f;
        /// <summary>
        /// Elapsed time when keyboard key is being pressed.
        /// </summary>
        public static float KeyPressedElapsedTime
        {
            get { return Vate.keyPressedElapsedTime; }
            set { Vate.keyPressedElapsedTime = value; }
        }
        /// <summary>
        /// Elapsed time when next trigger key is being pressed.
        /// </summary>
        private static float keyPressedNextTriggerKey = 0f;
        /// <summary>
        /// Elapsed time when next trigger key is being pressed.
        /// </summary>
        public static float KeyPressedNextTriggerKey
        {
            get { return Vate.keyPressedNextTriggerKey; }
            set { Vate.keyPressedNextTriggerKey = value; }
        }
        #endregion

        #region Methods

        #region Keyboard
        /// <summary>
        /// Returns whether the specified key is currently being pressed.
        /// </summary>
        /// <param name="key">Keyboard key</param>
        public static bool IsKeyDown(Keys key)
        {
            if (keyboardState.IsKeyDown(key))
                return true;

            return false;
        }
        /// <summary>
        /// Returns whether the specified key is currently being pressed.
        /// </summary>
        /// <param name="key">Keyboard key</param>
        public static bool IsKeyDown(KeyboardKeys key)
        {
            return IsKeyDown((Keys)key);
        }
        /// <summary>
        /// Returns whether the specified key is pressed in stepping way.
        /// </summary>
        /// <param name="key">Keyboard key</param>
        public static bool IsStepKeyDown(Keys key)
        {
            if (IsKeyDown(key))
            {
                if (!oldKeyboardState.IsKeyDown(key))
                {
                    keyPressedElapsedTime = 0f;
                    keyPressedNextTriggerKey = 500f;
                    return true;
                }
                else
                {                    
                    keyPressedElapsedTime += TimeFactor;

                    if (keyPressedElapsedTime > keyPressedNextTriggerKey)
                    {
                        keyPressedElapsedTime = keyPressedNextTriggerKey - 30f;
                        return true;
                    }
                }
            }

            return false;
        }
        /// <summary>
        /// Returns whether the specified key is pressed in stepping way.
        /// </summary>
        /// <param name="key">Keyboard key</param>
        public static bool IsStepKeyDown(KeyboardKeys key)
        {
            return IsStepKeyDown((Keys)key);
        }
        /// <summary>
        /// Returns whether the shift key is being pressed.
        /// </summary>
        public static bool IsShiftKeyDown()
        {
            if (IsKeyDown(KeyboardKeys.LeftShift) || IsKeyDown(KeyboardKeys.RightShift))
                return true;

            return false;
        }
        /// <summary>
        /// Returns alpha numeric char when alpha numeric keys are pressed in stepping way.
        /// </summary>
        public static char IsStepConsoleKeyDown()
        {
            int i;
            // check for numeric
            for (i = 48; i <= 57; i++)
            {
                if (IsStepKeyDown((Keys)i))
                    return (char)i;
            }
            // check for alpha
            for (i = 65; i <= 90; i++)
            {
                if (IsStepKeyDown((Keys)i))
                    return (char)i;
            }
            // check for space
            if (IsStepKeyDown(KeyboardKeys.Space))
                return ' ';

            return '_';
        }
        #endregion

        #region Mouse
        /// <summary>
        /// Returns whether the left mouse button is being pressed.
        /// </summary>
        public static bool IsLeftPressed()
        {
            if (mouseState.LeftButton == ButtonState.Pressed)
                return true;

            return false;
        }
        /// <summary>
        /// Returns whether the left mouse button is pressed in stepping way.
        /// </summary>
        public static bool IsStepLeftPressed()
        {
            if (IsLeftPressed())
            {
                if (oldMouseState.LeftButton == ButtonState.Released)
                    return true;
            }

            return false;
        }
        /// <summary>
        /// Returns whether the middle mouse button is being pressed.
        /// </summary>
        public static bool IsMiddlePressed()
        {
            if (mouseState.MiddleButton == ButtonState.Pressed)
                return true;

            return false;
        }
        /// <summary>
        /// Returns whether the right mouse button is being pressed.
        /// </summary>
        public static bool IsRightPressed()
        {
            if (mouseState.RightButton == ButtonState.Pressed)
                return true;

            return false;
        }
        /// <summary>
        /// Returns whether the right mouse button is pressed in stepping way.
        /// </summary>
        public static bool IsStepRightPressed()
        {
            if (IsRightPressed())
            {
                if (oldMouseState.RightButton == ButtonState.Released)
                    return true;
            }

            return false;
        }
        /// <summary>
        /// Returns mouse position.
        /// </summary>
        public static Vector2 GetMousePosition()
        {
            return new Vector2(mouseState.X, mouseState.Y);
        }
        /// <summary>
        /// Sets mouse position on screen.
        /// </summary>
        /// <param name="position">Mouse position on screen in Vector2</param>
        public static void SetMousePosition(Vector2 position)
        {
            Mouse.SetPosition((int)position.X, (int)position.Y);
        }

        #endregion

        #endregion
    }
}
